package com.hjy.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

public class MyUtil {

    public static class Res {
        public List<String> imgUrls; // 实际文件地址
        public Map<String, String> urlMap; // 实际文件地址: 应该新存储文件地址
        public Map<String, String> urlMap2; // 文件中的url : 应该新存储文件地址

        public Res() {
            imgUrls = new ArrayList<>();
            urlMap = new HashMap<>();
            urlMap2 = new HashMap<>();
        }

        @Override
        public String toString() {
            return "Res{" +
                    "imgUrls=" + imgUrls +
                    ", urlMap=" + urlMap +
                    ", urlMap2=" + urlMap2 +
                    '}';
        }
    }

    /**
     * 获取一个路径的标准化, 如 C:\Users\24026/123/hello/12\33 => C:\Users\24026\123\hello\12\33
     * @param path
     * @return
     */
    public static String getStandardPath(String path) {
        try {
            return new File(path).getCanonicalPath();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取s1相对于s2的相对路径
     * 如 s1 "C:\\Users\\24026\\Desktop\\test\\media\\TyporaImg\\img3\\wps18.png"
     * 如 s2 "C:\\Users\\24026\\Desktop\\test\\hadoop\\Hadoop3.1.3.md"
     * 返回 ..\media\TyporaImg\img3\wps18.png
     *
     * @param path1
     * @param path2
     * @return
     */
    public static String getRelativePath(String path1, String path2) {
        Path p1 = Paths.get(path1);
        Path p2 = Paths.get(path2);
        String path = p2.getParent().relativize(p1.getParent()) + "\\" + p1.getFileName();
        if (p1.getParent().toString().startsWith(p2.getParent().toString())) {
            path = ".\\" + path;
        }
        return path;
    }

    /**
     * 获取path2基于path1的绝对路径
     *
     * @param path1 "C:\\Users\\24026\\Desktop\\test\\hadoop\\xxx.md"
     * @param path2 "..\\media\\wps18.png"
     * @return C:\Users\24026\Desktop\test\media\wps18.png
     * @throws IOException
     */
    public static String getAbsolutePath(String path1, String path2) throws IOException {
        File file1 = new File(Paths.get(path1).getParent().toString());
        File file2 = new File(file1.getAbsolutePath() + "\\" + path2);
        return file2.getCanonicalPath();
    }

    /**
     * 根据文件内容, 获取其所有的图片路径, 返回新的对应的文件路径
     *
     * @param filePrefix            图片前缀
     * @param newFilePrefix         转换后的图片前缀, 若为 null 等于 filePrefix
     * @param fileContent           文件内容
     * @param afterChangeFilePrefix 转换后图片文件存储在哪里
     */
    public static Res getImgUrls(String filePrefix, String newFilePrefix, String fileContent, String
            afterChangeFilePrefix) {
        if (fileContent == null) {
            return null;
        }

        if (newFilePrefix.equals("")) {
            newFilePrefix = filePrefix;
        }

        // 图片可能的后缀
        List<String> fileExtend = new ArrayList<>(Arrays.asList(".gif", ".png", ".jpg", ".jpeg"));
        // 结果封装
        Map<String, String> map = new HashMap<>();
        Map<String, String> map2 = new HashMap<>();
        List<String> list = new ArrayList<>();
        // 文件开始下标
        int indexId = 0;
        while (true) {
            indexId = fileContent.indexOf(filePrefix, indexId);
            if (indexId == -1) {
                break;
            }
            // 标识一张本地图片的最后字符位置
            Integer fileEndPosition = Integer.MAX_VALUE;
            // 这张图片的类型, 如 png, jpg 等等
            String type = "";
            // 找到这张图片的末尾位置
            for (String extend : fileExtend) {
                int tmp = fileContent.indexOf(extend, indexId);
                if (tmp == -1) {
                    tmp = Integer.MAX_VALUE;
                }
                if (fileEndPosition >= tmp) {
                    type = extend;
                    fileEndPosition = tmp;
                }
            }
            fileEndPosition += type.length();
            // 这张图片不可能 url > 100, 说明出问题了
            if (fileEndPosition - indexId > 100) {
                indexId += 100;
                continue;
            }

            try {
                // 图片文件除去前缀的名字
                String substring = fileContent.substring(indexId + filePrefix.length(), fileEndPosition);
                // 更新后的图片输出位置
                String fileName = getStandardPath(afterChangeFilePrefix + substring);
                list.add(getStandardPath(newFilePrefix + substring));
                //  源图片位置 : 图片输出位置
                map.put(getStandardPath(newFilePrefix + substring), fileName);
                // 在文件中文件字符串 : 图片输出位置
                map2.put(fileContent.substring(indexId, fileEndPosition), fileName);
                indexId += filePrefix.length();
            } catch (Exception e) {
                System.out.println(indexId + filePrefix.length() + " " + fileEndPosition + " " + fileContent.substring(indexId + filePrefix.length(), indexId + filePrefix.length() + 25));
                break;
            }
        }
        Res res = new Res();
        res.imgUrls = list;
        res.urlMap = map;
        res.urlMap2 = map2;
        return res;
    }

    /**
     * 获取 md 文件中所有的相对路径的图片路径
     *
     * @param mdFile md 文件
     * @return res
     */
    public static Res getRelativeImgUrls(File mdFile, String newAbsoluteImgFolder) {
        List<String> relative = new ArrayList<>(Arrays.asList("../", "./", "..\\", ".\\"));
        // 图片可能的后缀
        List<String> fileExtend = new ArrayList<>(Arrays.asList(".gif", ".png", ".jpg", ".jpeg"));
        // 结果封装
        Map<String, String> map = new HashMap<>();
        Map<String, String> map2 = new HashMap<>();
        List<String> list = new ArrayList<>();
        String fileContent = getFileContent(mdFile);
        // 文件开始下标
        int indexId = 0;
        for (String filePrefix : relative) {
            while (true) {
                indexId = fileContent.indexOf(filePrefix, indexId);
                if (indexId == -1) {
                    break;
                }
                // 标识一张本地图片的最后字符位置
                Integer fileEndPosition = Integer.MAX_VALUE;
                // 这张图片的类型, 如 png, jpg 等等
                String type = "";
                // 找到这张图片的末尾位置
                for (String extend : fileExtend) {
                    int tmp = fileContent.indexOf(extend, indexId);
                    if (tmp == -1) {
                        tmp = Integer.MAX_VALUE;
                    }
                    if (fileEndPosition >= tmp) {
                        type = extend;
                        fileEndPosition = tmp;
                    }
                }
                fileEndPosition += type.length();
                // 这张图片不可能 url > 100, 说明出问题了
                if (fileEndPosition - indexId > 100) {
                    indexId += 100;
                    continue;
                }

                try {
                    // md 文件内部的图片地址, 相对路径
                    String inFileUrl = fileContent.substring(indexId, fileEndPosition);
                    // 实际图片位置
                    String absolutePath = getAbsolutePath(mdFile.getAbsolutePath(), inFileUrl);
                    if (!(new File(absolutePath).exists())) {
                        indexId += inFileUrl.length();
                        continue;
                    }
                    list.add(absolutePath);
                    // 图片文件内绝对路径 : 新图片路径
                    String fileName = getStandardPath(newAbsoluteImgFolder + "\\" + UUID.randomUUID() + new File(absolutePath).getName());
                    map.put(absolutePath, fileName);
                    map2.put(inFileUrl, fileName);
                    indexId += inFileUrl.length();
                } catch (Exception e) {
                    System.out.println(indexId + filePrefix.length() + " " + fileEndPosition + " " + fileContent.substring(indexId + filePrefix.length(), indexId + filePrefix.length() + 25));
                    break;
                }

            }
        }
        Res res = new Res();
        res.imgUrls = list;
        res.urlMap = map;
        res.urlMap2 = map2;
        return res;
    }

    /**
     * 获取文件夹下所有的 md 文件
     *
     * @param folder md 文件所在文件夹对象
     * @return 所有的 md 文件对象
     */
    public static List<File> getAllMdFile(File folder) {
        File[] files = folder.listFiles();
        List<File> mdFiles = new ArrayList<>();
        assert files != null;
        for (File file : files) {
            if (file.isHidden()) {
                continue;
            } else if (file.isDirectory()) {
                mdFiles.addAll(getAllMdFile(file));
            } else if (file.isFile() && getFileExtension(file).equals("md")) {
                mdFiles.add(file);
            }
        }
        return mdFiles;
    }

    /**
     * 获取文件后缀名
     *
     * @param file 文件对象
     * @return 后缀名, 如果没有就 " "
     */
    public static String getFileExtension(File file) {
        String fileName = file.getName();
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0)
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        else return " ";
    }

    /**
     * 获取文件内容
     *
     * @param file 文件对象
     * @return 文件内容
     */
    public static String getFileContent(File file) {
        try {
            return IoUtil.read(new FileInputStream(file)).toString();
        } catch (FileNotFoundException e) {
            System.err.println("文件" + file.getAbsolutePath() + "不存在");
        }
        return null;
    }

    /**
     * 写入文件内容, 覆盖写入
     *
     * @param file        对应的文件
     * @param fileContent 写入文件的内容
     * @return 返回文件对象
     */
    public static File saveFileContent(File file, String fileContent) {
        if (!file.exists()) {
            FileUtil.touch(file);
        }
        return FileUtil.writeString(fileContent, file, StandardCharsets.UTF_8);
    }
}
